﻿/***************
 * Copyright 2009 (C) 
 * Timur Fanshteyn
 * Blog: http://blog.tfanshteyn.com
 * ************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using System.Collections.ObjectModel;

namespace Coherence.Linq
{
    internal class CoherenceExpressionVisitor : ExpressionVisitor
    {
        protected override Expression Visit(Expression exp)
        {
            if (exp == null)
            {
                return null;
            }
            switch ((CoherenceExpressionType)exp.NodeType)
            {
                case CoherenceExpressionType.Select:
                    return this.VisitSelect((SelectExpression)exp);
                case CoherenceExpressionType.Projection:
                    return this.VisitProjection((ProjectionExpression)exp);
                default:
                    return base.Visit(exp);
            }
        }

        protected virtual Expression VisitSelect(SelectExpression select)
        {
            Expression from = this.VisitSource(select.From);
            Expression where = this.Visit(select.Where);
            if (from != select.From || where != select.Where)
            {
                return new SelectExpression(select.Type, from, where);
            }
            return select;
        }

        protected virtual Expression VisitSource(Expression source)
        {
            return this.Visit(source);
        }

        protected virtual Expression VisitProjection(ProjectionExpression proj)
        {
            SelectExpression source = (SelectExpression)this.Visit(proj.Source);
            Expression projector = this.Visit(proj.Projector);
            if (source != proj.Source || projector != proj.Projector)
            {
                return new ProjectionExpression(source, projector);
            }
            return proj;
        }
    }
}
